package cn.fzkj.procedure05;

import akka.actor.*;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import akka.japi.function.Procedure;
import scala.PartialFunction;
import scala.Unit;
import scala.runtime.BoxedUnit;

/**
 * @ author mr
 * @ description
 * @ since 2024/12/2
 */
public class ProcedureTest extends AbstractActor {

    private final LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);

    // Define the happy and angary behaviors (as Receive)
    private final Receive angary = receiveBuilder()
            .matchEquals(Msg.PLAY, msg -> {
                log.info("time to angary to play..");
            })
            .matchEquals(Msg.SLEEP, msg -> {
                log.info("Still angry, don't bother me!");
            })
            .build();


    private final Receive happy = receiveBuilder()
            .matchEquals(Msg.PLAY, msg -> {
                log.info("Already playing!");
            })
            .matchEquals(Msg.SLEEP, msg -> {
                log.info("Time to sleep...");
                getContext().become(angary);  // 切换到愤怒状态
            })
            .matchAny(this::unhandled)  // 处理其他未匹配的消息
            .build();

    @Override
    public Receive createReceive() {
        return receiveBuilder()
                .matchEquals(Msg.SLEEP, msg -> {
                    log.info("SLEEP.");
                    getContext().become(angary);  // Transition to angary behavior
                })
                .matchEquals(Msg.PLAY, msg -> {
                    log.info("PLAY.");
                    getContext().become(happy);  // Transition to happy behavior
                })
                .matchAny(this::unhandled)
                .build();
    }


    public static void main(String[] args) throws InterruptedException {
        ActorSystem system = ActorSystem.create("strategy");
        ActorRef procedureTest = system.actorOf(Props.create(ProcedureTest.class), "ProcedureTest");

        procedureTest.tell(Msg.PLAY, ActorRef.noSender()); // 给定初始状态
        procedureTest.tell(Msg.SLEEP, ActorRef.noSender()); // PLAY -> SLEEP  happy状态接收到SLEEP,切换成angary状态
        procedureTest.tell(Msg.PLAY, ActorRef.noSender()); // angary状态接收到PLAY
        procedureTest.tell(Msg.PLAY, ActorRef.noSender());

        procedureTest.tell(PoisonPill.getInstance(), ActorRef.noSender());
    }

    private enum Msg {
        PLAY, SLEEP
    }
}
